package com.example.demo.service;


import com.example.demo.polo.MyMessage;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Auther: Graycat
 * @Date: 2020/7/20 13:23
 * Create by lwj.
 */

@ServerEndpoint("/webSocket/{sid}")
@Component
public class WebSocketService {
    //在线人数，静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    //存放房间中的用户与房间号的对应关系
    public static HashMap<String ,String > userInRoom = new HashMap<>();


    public void sendMessage( Session session, String message ) throws IOException {
        if(session != null){
            //synchronized 保证线程互斥，线程同步哪里有说明
            synchronized (session) {
                //socket通过session发送消息，把json数据转换成socket可以传递的数据格式
                session.getBasicRemote().sendText(message);
            }
        }
    }


    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String userName){
        sessionPools.put(userName, session);
        addOnlineCount();
        System.out.println("连接建立成功调用："+ userName + "加入webSocket！当前人数为" + onlineNum);
//        try {
//            sendMessage(session, "欢迎" + userName + "加入连接！");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "sid") String userName){
        sessionPools.remove(userName);
        userInRoom.remove(userName);
        subOnlineCount();
        System.out.println(userName + "断开webSocket连接！当前人数为" + onlineNum);
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String message) throws IOException{
        System.out.println("客户端消息："+message);
        //消息由Json String转为MyMessage对象
        JSONObject jsonObject=JSONObject.fromObject(message);
        MyMessage msg=(MyMessage)JSONObject.toBean(jsonObject, MyMessage.class);
      //  System.out.println("msg:"+msg+" roomId:"+msg.getRoomId());
        String msgRoomId = msg.getRoomId();
        String msgUserId = msg.getUserId();
        List<String> userList = new ArrayList<>();  //房间内用户列表
        //给同一房间的人(除掉自己)发消息
        //判断同一房间的消息就转发出去。
        for (Map.Entry<String, String> userItem : userInRoom.entrySet()) {
            if (userItem.getValue().equals(msgRoomId)){
                userList.add(userItem.getKey());
                for (Map.Entry<String, Session> item1 : sessionPools.entrySet()) {
                    if ( item1.getKey().equals(userItem.getKey()) &&  !item1.getKey().equals(msgUserId)){
                        Session session = item1.getValue();
                        sendMessage(session,message);
                    }
                }
            }
        }
//        for (Session session: sessionPools.values()) {
//            try {
//                System.out.println(session+"  xxid :"+session.getId());
//                sendMessage(session, message);
//            } catch(Exception e){
//                e.printStackTrace();
//                continue;
//            }
//        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}
